> passed to change() as a pointer (to pointer),
No - its a pointer to an array, not a pointer to a pointer.
The "array is pointer to first element" rule is only applied once, not recursively.
> unless it assigned memory using the new operator, in which case it's not really a pointer anymore but an array!
Nope - its still a pointer
The fact that you can do ptr[index] on a pointer doesn't make it an array.
Because arrays are passed as a pointer to the first element of the array (in the case of 2D pointers, this in in fact a pointer to an array - namely one whole row of the 2D array), the called function is able to modify the contents of that array. So returning a pointer to it is seldom necessary.
But anyway, for those who are interested, this is the lowdown
Code:
#include <iostream>
using namespace std;
// func takes pointer to a 2D array as a parameter
// and returns a pointer to a 2D array
// this is not the same as int **func( int a[2][3] );
// remember, pointer to ARRAY, not pointer to POINTER
int (*func( int a[2][3] ))[3] {
for ( int r = 0 ; r < 2 ; r++ ) {
for ( int c = 0 ; c < 3 ; c++ ) {
a[r][c] = r * c;
}
}
return a;
}
// but that sure is messy to write (or remember even)
// oh yeah, parentheses matter - just try taking some out and see
// a typedef makes it so much easier
typedef int (*twodptr)[3];
twodptr func2 ( twodptr a ) {
for ( int r = 0 ; r < 2 ; r++ ) {
for ( int c = 0 ; c < 3 ; c++ ) {
a[r][c] = r * c;
}
}
return a;
}
int main() {
int a[2][3]; // a 2D array
int (*b)[3]; // a pointer to a 2D array (this is not the same as int**)
// specifically a 2D array with [3] as the minor dimension
twodptr c; // another pointer, just like b
int row,col;
b = func( a ); // pass array to func, get a pointer to the array back
c = func2( a );
// show a,b,c are the same
for ( row = 0 ; row < 2 ; row++ ) {
for ( col = 0 ; col < 3 ; col++ ) {
cout << a[row][col] << " "
<< b[row][col] << " "
<< c[row][col] << " ";
}
cout << endl;
}
// you can even allocate a 2D array in one step - with the right pointer type
// and pass it to the same function as before
b = new int[2][3]; // the minor dimension MUST MATCH
func( b );
for ( row = 0 ; row < 2 ; row++ ) {
for ( col = 0 ; col < 3 ; col++ ) {
cout << b[row][col] << " ";
}
cout << endl;
}
delete [] b;
return 0;
}